package com.ydlclass.loadbnlancer;

import com.ydlclass.YrpcBootstrap;
import com.ydlclass.discovery.Registry;

import java.net.InetSocketAddress;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 这个方法是模版设计模式，将getSelector抽象出来让方法去实现
 * @Author duWenJian
 * @Date 2023/11/4 16:15
 * @Version 1.0
 */
public abstract class AbstractLoadBalance implements LoadBalancer{
    // 缓存
    private Map<String,Selector> cache = new ConcurrentHashMap<>(8);

    @Override
    public InetSocketAddress selectServiceAddress(String serviceName) {
        Selector selector = cache.get(serviceName);
        // 缓存中没有,自己创建
        if (selector == null ){
            // todo 对于一个负载均衡器，内部应该维护一个服务列表作为缓存
            List<InetSocketAddress> addressesList = YrpcBootstrap.getInstance().getRegistry().lookup(serviceName);
            // todo 提供一些算法负责选取合适的节点
            selector = getSelector(addressesList);
            cache.put(serviceName,selector);
        }
        // 获取可用节点
        return selector.getNext();
    }

    @Override
    public synchronized void reLoadBalance(String serviceName,List<InetSocketAddress> addressesList) {
        // 我们可以根据新的服务列表生成新的Selector
        cache.put(serviceName,getSelector(addressesList));
    }

    /**
     * 由子类进行扩展
     * @param addressesList 服务列表
     * @return 负载均衡算法选择器
     */
    protected abstract Selector getSelector(List<InetSocketAddress> addressesList);

}
